<template>
  <div class="map-box">
    <Input id="tipinput" type="text" class="input-box" placeholder="请输入地址" />
    <div ref="wrapRef" id="container" :style="{ height: props.height, width: props.width }"></div>
  </div>
</template>
<script setup lang="ts">
  import { onMounted } from 'vue';
  import { Input } from 'ant-design-vue';
  import AMapLoader from '@amap/amap-jsapi-loader';
  const props = defineProps({
    width: {
      type: String,
      default: '50em',
    },
    height: {
      type: String,
      default: '50em',
    },
    // 默认值
    defaultValue: {
      type: Object,
      default: () => {},
    },
    // 门店信息
    store: {
      type: Object,
      default: () => {},
    },
  });
  //  返回两个参数 address : obj  详细地址  lnglat: 经纬度信息
  const emit = defineEmits(['change']);
  function initMap() {
    AMapLoader.load({
      key: 'c4dadbbc97c23178ce316a148bc59470', // 申请好的Web端开发者Key，首次调用 load 时必填
      version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
      // 需要使用的的插件列表，如比例尺'AMap.Scale'等
      plugins: [
        'AMap.Scale',
        'AMap.Geolocation',
        'AMap.Marker',
        'AMap.Geocoder',
        'AMap.PlaceSearch',
        'AMap.AutoComplete',
        'AMap.LngLat',
        'AMap.InfoWindow',
        'AMap.Pixel',
      ],
      AMapUI: {
        // 是否加载 AMapUI，缺省不加载
        version: '1.1', // AMapUI 缺省 1.1
        plugins: [], // 需要加载的 AMapUI ui插件
      },
      Loca: {
        // 是否加载 Loca， 缺省不加载
        version: '2.0', // Loca 版本，缺省 1.3.2
      },
    })
      .then((AMap) => {
        const map = new AMap.Map('container', {
          zoom: 15, // 地图缩放级别
          resizeEnable: true,
        });
        const geocoder = new AMap.Geocoder();
        const auto = new AMap.AutoComplete({
          input: 'tipinput',
        });

        let infoWindow = new AMap.InfoWindow({ offset: new AMap.Pixel(0, -30) }); // 信息窗口

        const placeSearch = new AMap.PlaceSearch({
          map: map,
        });
        const geolocation = new AMap.Geolocation({
          enableHighAccuracy: true, //  是否使用高精度定位，默认:true
          timeout: 10000, //  超过10秒后停止定位，默认：无穷大
          maximumAge: 0, // 定位结果缓存0毫秒，默认：0
          convert: true, // 自动偏移坐标，偏移后的坐标为高德坐标，默认：true
          showButton: true, //  显示定位按钮，默认：true
          buttonPosition: 'LB', // 定位按钮停靠位置，默认：'LB'，左下角
          buttonOffset: new AMap.Pixel(10, 20), //  定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
          showMarker: true, //  定位成功后在定位到的位置显示点标记，默认：true
          showCircle: true, //  定位成功后用圆圈表示定位精度范围，默认：true
          panToLocation: true, //  定位成功后将定位到的位置作为地图中心点，默认：true
          zoomToAccuracy: true, //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
        });
        auto.on('select', select); //注册监听，当选中某条记录时会触发
        function select(e) {
          placeSearch.setCity(e.poi.adcode);
          placeSearch.search(e.poi.name); //关键字查询查询
          lnglatOrAddress(e.poi.location);
        }

        // 定位中心位置
        // map.center = geolocation;

        map.addControl(geolocation);
        const marker = new AMap.Marker({
          position: geolocation,
        });
        marker.on('click', () => {
          showWindowInfo();
        });
        // 获取精确位置
        geolocation.getCurrentPosition(function (status, result) {
          if (status == 'complete') {
            map.center = result.position;
          } else {
            onError(result);
          }
        });
        // 选择点坐标
        map.on('click', function (e) {
          const lnglat = e.lnglat;
          lnglatOrAddress(lnglat);
          marker.setPosition([lnglat.lng, lnglat.lat]);
          map.add(marker); //添加到地图
          showWindowInfo();
        });
        // 对获取的地址进行处理
        function formatAddress(res) {
          let address = res.regeocode.formattedAddress;
          address = address.replace(res.regeocode.addressComponent.city, '');
          address = address.replace(res.regeocode.addressComponent.province, '');
          address = address.replace(res.regeocode.addressComponent.district, '');
          return address;
        }
        // 当填写默认经纬度时获取当前地址
        function getDefaultAddress() {
          const { lng, lat } = props.defaultValue;
          // 没有经纬度返回空
          if (!lng && !lat) return emit('change', {});
          lnglatOrAddress({ lat, lng });
          // 添加图标
          marker.setPosition([lng, lat]);
          // 设置中心点
          setTimeout(() => {
            map.setCenter([lng, lat]);
          }, 500);

          showWindowInfo();
          map.add(marker);
        }
        getDefaultAddress();
        // 通过经纬度获取地址详情、编码
        function lnglatOrAddress(lnglat) {
          geocoder.getAddress(lnglat, function (status, result) {
            if (status === 'complete' && result.info === 'OK') {
              let detail = formatAddress(result);
              emit('change', { detail }, lnglat);
            }
          });
        }
        // 解析定位错误信息
        function onError(data) {
          console.log('getCityInfo=>result', '定位失败');
          console.log('失败原因排查信息:' + data.message);
        }
        // 展示信息窗口
        /**
         * 展示信息窗口
         */
        function showWindowInfo() {
          if (!marker) return;
          var info: string[] = [];
          info.push(
            `<div style=\"padding:7px 0px 0px 0px;\"><h3>${
              props.store.store_name || '未填写'
            }</h3>`,
          );
          info.push(`<p class='input-item'>电话 : ${props.store.phone || '未填写'}</p>`);
          info.push(
            `<p class='input-item'>地址 :${props.store.detail || '未填写'}</p></div></div>`,
          );
          info.push(
            `<p class='input-item'>详细 :${props.store.doorplate || '未填写'}</p></div></div>`,
          );
          infoWindow = new AMap.InfoWindow({
            content: info.join(''), //使用默认信息窗体框样式，显示信息内容
          });
          infoWindow.open(map, marker.getPosition());
        }

        // 添加/更新 Marker中心点位置
        //  function updateMarker() {
        //     let postion = new AMap.LngLat(center.lng, center.lat)
        //     map.setCenter(postion, false, 500)
        //     if (marker) return marker.setPosition(postion)
        //     marker.on('click', () => {
        //       showWindowInfo()
        //     })
        //   };
      })
      .catch((e) => {
        console.log(e);
      });
  }

  onMounted(() => {
    initMap();
  });
</script>

<style lang="less" scoped>
  .map-box {
    position: relative;

    .input-box {
      width: 15em;
      position: absolute;
      top: 2em;
      left: 1em;
      z-index: 9;
    }
  }
</style>
